package com.arethusa;

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.view.JRViewer;
import simpleorm.core.SConnection;
import simpleorm.core.SPreparedStatement;
import simpleorm.core.SResultSet;
import simpleorm.core.SValidationException;
import simpleorm.ui.SUIConstants;

import com.arethusa.officialdb.Gefungeerdin;
import com.arethusa.officialdb.GefungeerdinBean;
import com.arethusa.officialdb.Official;
import com.arethusa.officialdb.OfficialBean;
import com.ibm.j2x.swing.util.TableUtilities;
import com.ibm.j2x.util.CollectionUtilities;

public class OfficialsList extends JPanel  implements SUIConstants, MouseListener {

	private static final long serialVersionUID = 1L;
	private JPanel jButtonPanel = null;
	private JScrollPane jScrollPane = null;
	private JTable jTable = null;
	private JButton InvoerButton = null;
	private JButton WijzigButton = null;
	private JButton VerwijderButton = null;
	private JButton UitnodigButton = null;
	
	private String sortBy = "Achternaam";  //  @jve:decl-index=0:
	private Boolean sortAscending = new Boolean(true);
	private String filter = "NOFILTER";  //  @jve:decl-index=0:
	private List<?> olist;
	private JButton filter1Button = null;
	private JButton envelopButton = null;
	private JButton briefButton = null;
	private JPanel previewPanel = null;


	private class TableSorter extends MouseAdapter {
        public void mouseClicked(MouseEvent e) {
            TableColumnModel columnModel = jTable.getColumnModel();
            int viewColumn = columnModel.getColumnIndexAtX(e.getX()); 
            int column = jTable.convertColumnIndexToModel(viewColumn); 
            if(e.getClickCount() == 1 && column != -1) {
                sortAscending = new Boolean(!sortAscending.booleanValue());
                sortBy = jTable.getModel().getColumnName(column);
                fillTable(sortBy, sortAscending);
            }
         }
	}
	
	private class VoerinActionListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			NewOfficialDetails();
		}
		
	}

	private class WijzigActionListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			ShowOfficialDetails();
		}
		
	}

	private class VerwijderActionListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			DeleteOfficial();
		}
		
	}

	private class NodiguitActionListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			if( getUitnodigButton().getText().equalsIgnoreCase("Nodig uit") ) {
				InviteOfficials();
			} else {
				UninviteOfficials();
			}
		}
		
	}

	private class Filter1ActionListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			if( filter.equalsIgnoreCase("NOFILTER") ) {
				filter="INVITED";
				getFilter1Button().setText("Allemaal");
				getUitnodigButton().setText("Nodig niet uit");
				getInvoerButton().setEnabled(false);
				getWijzigButton().setEnabled(false);
				getVerwijderButton().setEnabled(false);
			} else {
				filter="NOFILTER";
				filter1Button.setText("Alleen uitgenodigden");
				getUitnodigButton().setText("Nodig uit");
				getInvoerButton().setEnabled(true);
				getWijzigButton().setEnabled(true);
				getVerwijderButton().setEnabled(true);
			}
			fillTable(sortBy, sortAscending);
		}
		
	}

	private class PrintEnvelopActionListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			boolean hasBegun = SConnection.getConnection().hasBegun();
			PrintPreviewDialog prvw = new PrintPreviewDialog();
			String lijst = null;
			lijst = "reports\\Envelop.jasper";
			
			JasperPrint prt = new JasperPrint();
			try {
				if( ! hasBegun ) { SConnection.begin(); }
				prt = JasperFillManager.fillReport(lijst, null, SConnection.getBegunDBConnection());
				SConnection.commit();
				if( hasBegun ) { SConnection.begin(); }
			} catch (JRException re) {
				JOptionPane.showMessageDialog(null,
						re.getMessage()+re.getCause(),
						"Report foutmelding", JOptionPane.ERROR_MESSAGE);
				SConnection.commit();
			}
			if( previewPanel != null) prvw.remove(previewPanel);
			previewPanel = new JRViewer(prt);
			prvw.getContentPane().add(previewPanel, java.awt.BorderLayout.CENTER);
			prvw.setSize(800,950);
			prvw.setVisible(true);
		}
		
	}

	private class PrintBriefActionListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			boolean hasBegun = SConnection.getConnection().hasBegun();
			PrintPreviewDialog prvw = new PrintPreviewDialog();
			String lijst = null;
			lijst = "reports\\Brief.jasper";
			
			JasperPrint prt = new JasperPrint();
			try {
				if( ! hasBegun ) { SConnection.begin(); }
				prt = JasperFillManager.fillReport(lijst, null, SConnection.getBegunDBConnection());
				SConnection.commit();
			} catch (JRException re) {
				JOptionPane.showMessageDialog(null,
						re.getMessage()+re.getCause(),
						"Report foutmelding", JOptionPane.ERROR_MESSAGE);
				SConnection.commit();
			}
			if( previewPanel != null) prvw.remove(previewPanel);
			previewPanel = new JRViewer(prt);
			prvw.getContentPane().add(previewPanel, java.awt.BorderLayout.CENTER);
			prvw.setSize(800,950);
			prvw.setVisible(true);
		}
		
	}

	
	/**
	 * This is the default constructor
	 */
	public OfficialsList() {
		super();
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setLayout(new BorderLayout());
		this.setSize(534, 357);
		this.add(getJButtonPanel(), BorderLayout.NORTH);
		this.add(getJScrollPane(), BorderLayout.CENTER);
		fillTable(sortBy,sortAscending);
	}

	/**
	 * This method initializes jButtonPanel	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJButtonPanel() {
		if (jButtonPanel == null) {
			GridBagConstraints gridBagConstraints21 = new GridBagConstraints();
			gridBagConstraints21.gridx = 6;
			gridBagConstraints21.insets = new Insets(3, 3, 3, 3);
			gridBagConstraints21.fill = GridBagConstraints.BOTH;
			gridBagConstraints21.gridy = 0;
			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
			gridBagConstraints11.gridx = 5;
			gridBagConstraints11.insets = new Insets(3, 3, 3, 3);
			gridBagConstraints11.fill = GridBagConstraints.BOTH;
			gridBagConstraints11.gridy = 0;
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.gridx = 4;
			gridBagConstraints.insets = new Insets(3, 3, 3, 3);
			gridBagConstraints.fill = GridBagConstraints.BOTH;
			gridBagConstraints.gridy = 0;
			GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
			gridBagConstraints4.gridx = 3;
			gridBagConstraints4.insets = new Insets(3, 3, 3, 3);
			gridBagConstraints4.fill = GridBagConstraints.BOTH;
			gridBagConstraints4.gridy = 0;
			GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
			gridBagConstraints3.gridx = 2;
			gridBagConstraints3.insets = new Insets(3, 3, 3, 3);
			gridBagConstraints3.fill = GridBagConstraints.BOTH;
			gridBagConstraints3.gridy = 0;
			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
			gridBagConstraints2.gridx = 1;
			gridBagConstraints2.fill = GridBagConstraints.BOTH;
			gridBagConstraints2.insets = new Insets(3, 3, 3, 3);
			gridBagConstraints2.gridy = 0;
			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
			gridBagConstraints1.gridx = 0;
			gridBagConstraints1.fill = GridBagConstraints.BOTH;
			gridBagConstraints1.gridy = 0;
			gridBagConstraints1.insets = new Insets(3, 3, 3, 3);
			jButtonPanel = new JPanel();
			jButtonPanel.setLayout(new GridBagLayout());
			jButtonPanel.add(getInvoerButton(), gridBagConstraints1);
			jButtonPanel.add(getWijzigButton(), gridBagConstraints2);
			jButtonPanel.add(getVerwijderButton(), gridBagConstraints3);
			jButtonPanel.add(getUitnodigButton(), gridBagConstraints4);
			jButtonPanel.add(getFilter1Button(), gridBagConstraints);
			jButtonPanel.add(getEnvelopButton(), gridBagConstraints11);
			jButtonPanel.add(getBriefButton(), gridBagConstraints21);
		}
		return jButtonPanel;
	}

	/**
	 * This method initializes jScrollPane	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getJScrollPane() {
		if (jScrollPane == null) {
			jScrollPane = new JScrollPane();
			jScrollPane.setViewportView(getJTable());
		}
		return jScrollPane;
	}

	/**
	 * This method initializes jTable	
	 * 	
	 * @return javax.swing.JTable	
	 */
	private JTable getJTable() {
		if (jTable == null) {
			jTable = new JTable();
//			 Make column header click result in sorting ascending (shift-click is descending)
			jTable.setColumnSelectionAllowed(false);
	        TableSorter listSorter = new TableSorter();
			JTableHeader th = jTable.getTableHeader();
	        th.addMouseListener(listSorter); 
	        jTable.addMouseListener(this);
		}
		return jTable;
	}

	/**
	 * This method initializes InvoerButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getInvoerButton() {
		if (InvoerButton == null) {
			InvoerButton = new JButton();
			InvoerButton.setText("Voer in");
			InvoerButton.addActionListener(new VoerinActionListener());
		}
		return InvoerButton;
	}

	/**
	 * This method initializes WijzigButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getWijzigButton() {
		if (WijzigButton == null) {
			WijzigButton = new JButton();
			WijzigButton.setText("Wijzig");
			WijzigButton.addActionListener(new WijzigActionListener());
		}
		return WijzigButton;
	}

	/**
	 * This method initializes VerwijderButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getVerwijderButton() {
		if (VerwijderButton == null) {
			VerwijderButton = new JButton();
			VerwijderButton.setText("Verwijder");
			VerwijderButton.addActionListener(new VerwijderActionListener());
		}
		return VerwijderButton;
	}

	/**
	 * This method initializes UitnodigButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getUitnodigButton() {
		if (UitnodigButton == null) {
			UitnodigButton = new JButton();
			UitnodigButton.setText("Nodig uit");
			UitnodigButton.addActionListener(new NodiguitActionListener());
		}
		return UitnodigButton;
	}
	
	private void fillTable(String sortBy, Boolean ascending) {
		List<OfficialBean> tmp = new ArrayList<OfficialBean>();
		/// Prepare and execute the query
		boolean hasBegun = SConnection.getConnection().hasBegun();
		if( ! hasBegun ) { SConnection.begin(); }
		if( filter.equalsIgnoreCase("NOFILTER") ) {
			SPreparedStatement stmt = Official.meta.select(
					"1=1", sortBy+(ascending.booleanValue()?"":" DESC"));
			SResultSet res = stmt.execute();
			while (res.hasNext()) {
				OfficialBean strt = new OfficialBean(((Official)res.getRecord()));
				tmp.add(strt);
			}
			
		} else if( filter.equalsIgnoreCase("INVITED") ) {
			int yr = Calendar.getInstance().get(Calendar.YEAR);
			SPreparedStatement stmt = Gefungeerdin.meta.select(
					"Jaar="+yr+" AND Gevraagd=1 AND Reden=''", "OfficialId");
			SResultSet res = stmt.execute();
			while (res.hasNext()) {
				GefungeerdinBean f = new GefungeerdinBean(((Gefungeerdin)res.getRecord()));
				SPreparedStatement stmt1 = Official.meta.select(
						"OfficialId="+f.getOfficialid(), "Achternaam");
				SResultSet res1 = stmt1.execute();
				res1.hasNext();
				OfficialBean strt = new OfficialBean(((Official)res1.getRecord()));
				tmp.add(strt);
			}
			
		}
		
		/// loop through the results
		if( ! hasBegun ) { SConnection.commit(); }
    	olist = CollectionUtilities.observableList(tmp);
		TableUtilities.setViewToModel("OfficialModel.xml", "OfficialList", getJTable(), olist);
		int i=0;
		TableColumn col0 = getJTable().getColumnModel().getColumn(i);
		col0.setPreferredWidth(20);
//		TableColumn col1 = getJTable().getColumnModel().getColumn(++i);
//		col1.setPreferredWidth(0);
		TableColumn col2 = getJTable().getColumnModel().getColumn(++i);
		col2.setPreferredWidth(250);
		TableColumn col3 = getJTable().getColumnModel().getColumn(++i);
		col3.setPreferredWidth(30);
		TableColumn col4 = getJTable().getColumnModel().getColumn(++i);
		col4.setPreferredWidth(30);
		TableColumn col5 = getJTable().getColumnModel().getColumn(++i);
		col5.setPreferredWidth(100);
		TableColumn col6 = getJTable().getColumnModel().getColumn(++i);
		col6.setPreferredWidth(20);
		TableColumn col7 = getJTable().getColumnModel().getColumn(++i);
		col7.setPreferredWidth(20);
		TableColumn col8 = getJTable().getColumnModel().getColumn(++i);
		col8.setPreferredWidth(20);
		TableColumn col9 = getJTable().getColumnModel().getColumn(++i);
		col9.setPreferredWidth(20);
		TableColumn col10 = getJTable().getColumnModel().getColumn(++i);
		col10.setPreferredWidth(20);
		TableColumn col11 = getJTable().getColumnModel().getColumn(++i);
		col11.setPreferredWidth(20);
	}

	public void NewOfficialDetails() {
		OfficialBean o = new OfficialBean();
		o.setOfficialid(new Long(0));
		o.setEchtpaar(false);
		o.setJs(false);
		o.setKa(false);
		o.setSr(false);
		o.setSt(false);
		o.setT3(false);
		o.setT4(false);
		o.setMark(false);
		OfficialDetails dlg = new OfficialDetails(null);
		dlg.setLocationRelativeTo(null);
		dlg.setOfficial(o);
		dlg.setVisible(true);
		fillTable(sortBy, sortAscending);
	}
	
	public void ShowOfficialDetails() {
		if(getJTable().getSelectedRowCount()==0) {
			JOptionPane.showMessageDialog(null,
					"Selecteer eerst 1 official uit de tabel.",
					"Selectie fout", JOptionPane.INFORMATION_MESSAGE);
		} else if(getJTable().getSelectedRowCount()>1) {
			JOptionPane.showMessageDialog(null,
					"Selecteer slechts 1 official uit de tabel.",
					"Selectie fout", JOptionPane.INFORMATION_MESSAGE);
		}
		int row = getJTable().getSelectedRow();
		OfficialBean o = ((OfficialBean)olist.get(row));
		o.read();
		OfficialDetails dlg = new OfficialDetails(null);
		dlg.setLocationRelativeTo(null);
		dlg.setOfficial(o);
		dlg.setVisible(true);
		fillTable(sortBy, sortAscending);
	}
	
	public void DeleteOfficial() {
		if(getJTable().getSelectedRowCount()==0) {
			JOptionPane.showMessageDialog(null,
					"Selecteer eerst een official uit de tabel.",
					"Selectie fout", JOptionPane.INFORMATION_MESSAGE);
		} else if(getJTable().getSelectedRowCount()>1) {
			JOptionPane.showMessageDialog(null,
					"Selecteer slechts 1 official uit de tabel.",
					"Selectie fout", JOptionPane.INFORMATION_MESSAGE);
		}
		int row = getJTable().getSelectedRow();
		OfficialBean o = ((OfficialBean)olist.get(row));
		// check if official has functioned in one of our LBs
		boolean hasBegun = SConnection.getConnection().hasBegun();
		if( ! hasBegun ) { SConnection.begin(); }
		SPreparedStatement stmt = Gefungeerdin.meta.select(
				"OfficialID="+o.getOfficialid(), "JAAR");
		SResultSet res = stmt.execute();
		if( ! hasBegun ) { SConnection.commit(); }
		if(res.hasNext()) { //has functioned, so mark him
			o.read();
			o.setMark(true);
			o.update();
		} else {	// has not functioned yet, so remove
			o.delete();
		}
		fillTable(sortBy, sortAscending);
	}
	
	public void InviteOfficials() {
		if(getJTable().getSelectedRowCount()==0) {
			JOptionPane.showMessageDialog(null,
					"Selecteer eerst een of meerdere officials uit de tabel.",
					"Selectie fout", JOptionPane.INFORMATION_MESSAGE);
		} else {
			int rows[] = getJTable().getSelectedRows();
			for (int row : rows) {
				try {
					((OfficialBean)olist.get(row)).invite();
					JOptionPane.showMessageDialog(null,
							"Official(s) is(zijn) uitgenodigd.",
							"Uitnodiging", JOptionPane.INFORMATION_MESSAGE);
				} catch (SValidationException e) {
					JOptionPane.showMessageDialog(null,
							"Official is reeds uitgenodigd.",
							"Uitnodiging fout", JOptionPane.WARNING_MESSAGE);
				}
			}
		}
		
	}
	
	public void UninviteOfficials() {
		if(getJTable().getSelectedRowCount()==0) {
			JOptionPane.showMessageDialog(null,
					"Selecteer eerst een of meerdere officials uit de tabel.",
					"Selectie fout", JOptionPane.INFORMATION_MESSAGE);
		} else {
			int rows[] = getJTable().getSelectedRows();
			for (int row : rows) {
				try {
					((OfficialBean)olist.get(row)).uninvite();
				} catch (SValidationException e) {
					JOptionPane.showMessageDialog(null,
							e.getMessage(),
							"Uitnodiging fout", JOptionPane.INFORMATION_MESSAGE);
				}
			}
		}
		
	}
	
	public void mouseClicked(MouseEvent e) {
		int n = e.getClickCount();
		if(n==1) return;
		ShowOfficialDetails();
	}

	public void mouseEntered(MouseEvent e) {}

	public void mouseExited(MouseEvent e) {}

	public void mousePressed(MouseEvent e) {}

	public void mouseReleased(MouseEvent e) {}

	/**
	 * This method initializes filter1Button	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getFilter1Button() {
		if (filter1Button == null) {
			filter1Button = new JButton();
			filter1Button.setText("Alleen uitgenodigden");
			filter1Button.addActionListener(new Filter1ActionListener());
		}
		return filter1Button;
	}

	/**
	 * This method initializes envelopButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getEnvelopButton() {
		if (envelopButton == null) {
			envelopButton = new JButton();
			envelopButton.setText("Print Enveloppen");
			envelopButton.addActionListener(new PrintEnvelopActionListener());
		}
		return envelopButton;
	}

	/**
	 * This method initializes briefButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getBriefButton() {
		if (briefButton == null) {
			briefButton = new JButton();
			briefButton.setText("Print Brieven"); 
			briefButton.addActionListener(new PrintBriefActionListener());
		}
		return briefButton;
	}

}  //  @jve:decl-index=0:visual-constraint="10,10"
